﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

#if NETFX_CORE
using Windows.ApplicationModel.Resources;

#endif

namespace StyleMVVM.Validation.Impl.Fluent.Operators
{
	public class BinaryOperator<T> : BaseOperator<T>, IFluentBinaryOperator<T>
	{
		protected MethodInfo expressionMethod;

#if NETFX_CORE
		protected string InternalGenerateMessage(ResourceLoader fluentResources,
		                                         string resourceName)
		{
			string message = fluentResources.GetString(resourceName);

			if (!string.IsNullOrEmpty(message))
			{
				return string.Format(message,
				                     LeftValue.GenerateDisplayString(fluentResources),
				                     RightValue.GenerateDisplayString(fluentResources));
			}

			return string.Empty;
		}
#else
		protected string InternalGenerateMessage(string formatString)
		{
			if (!string.IsNullOrEmpty(formatString))
			{
				return string.Format(formatString, LeftValue.GenerateDisplayString(null), RightValue.GenerateDisplayString(null));
			}

			return string.Empty;
		}
#endif

		public override Expression GenerateExpression(IFluentExpressionProvider propertyExpressionProvider)
		{
			Expression lExpression = LeftValue.GenerateExpression(propertyExpressionProvider);
			Expression rExpression = RightValue.GenerateExpression(propertyExpressionProvider);

			if (expressionMethod.IsStatic)
			{
				return Expression.Call(expressionMethod,
				                       Expression.TypeAs(lExpression, typeof(object)),
				                       Expression.TypeAs(rExpression, typeof(object)));
			}

			throw new Exception("Operation method must be static: " + expressionMethod.Name);
		}

		public virtual IFluentValueProvider<T> LeftValue { get; set; }

		public virtual IFluentValueProvider<T> RightValue { get; set; }
	}
}